﻿/*******************************************************************************
 * @file flash.h
 * @brief flash操作
 *******************************************************************************
*/

#ifndef __FLASH_H__
#define __FLASH_H__

#include <stdint.h>
#include "stm32f10x.h"

#define FLASH_CAPACITY (*(volatile uint16_t*)0x1FFFF7E0) // flash大小 KB
#define FLASH_LIMIT (FLASH_BASE + (FLASH_CAPACITY<<10) - 1) // flash最大地址
#define FLASH_PAGE_SIZE 1024 // flash页大小

/**
 * @brief 获取指定地址所在的Flash页的基地址
 *
 * @param addr 给定地址
 * @return uint32_t 对齐后的页基地址
 */
__STATIC_INLINE uint32_t Flash_GetPageBase(uint32_t addr)
{
    // 使用位掩码快速对齐到页基地址
    return addr & ~(FLASH_PAGE_SIZE - 1);
}

/**
 * @brief 计算给定地址所在闪存页的末地址
 *
 * @param addr 给定地址
 * @return uint32_t 对应闪存页的最后一个地址
 */
__STATIC_INLINE uint32_t Flash_GetPageLimit(uint32_t addr)
{
    // 先获取基地址，再计算页末地址
    uint32_t base = addr & ~(FLASH_PAGE_SIZE - 1);
    return base + FLASH_PAGE_SIZE - 1;
}

/**
 * @brief 按照地址和大小擦除flash
 * @param addr 擦除地址，当擦除所有页时该参数不起作用
 * @param size 擦除大小，当传入 0xFFFFFFFF 时擦除所有页
 * @return 0 成功，-1 失败
 * @note flash擦除按页擦除，所以该函数会将您期望擦除的地址范围所在的页全部擦除
 *       本函数没有做解锁flash操作，擦除完也没做加锁操作，所以使用前/后，请做解锁/加锁
 */
int Flash_Erase(uint32_t addr, uint32_t size);

/**
 * @brief 批量写入flash
 * @param addr flash地址 2字节对齐
 * @param data 数据
 * @param size 数据长度 字节
 * @return 0成功 非0失败
 * @note 本函数没有做解锁flash操作，擦除完也没做加锁操作，所以使用前/后，请做解锁/加锁
 */
int Flash_Write(uint32_t addr, const uint16_t *data, uint32_t size);


#endif // FLASH_H
